package com.atom.module.picker

import android.app.Activity
import com.atom.module.picker.FileOpener.createChooseIntent
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.fragment.app.Fragment
import java.util.*
import java.util.concurrent.atomic.AtomicReference

object FileSelector {

    @JvmStatic
    private val mFileSelectCallBack: AtomicReference<FileSelectCallBack> =
        AtomicReference()

    @JvmStatic
    private var mRequestCode: Int = 2048

    @JvmStatic
    private var mIsMultiSelect: Boolean = false

    @JvmStatic
    private var mMimeType: String = FileMimeType.ALLTYPE

    @JvmStatic
    fun setMultiSelect(isMultiSelect: Boolean) {
        mIsMultiSelect = isMultiSelect
    }

    @JvmStatic
    fun setRequestCode(requestCode: Int) {
        mRequestCode = requestCode
    }

    @JvmStatic
    fun setMimeType(mimeType: String) {
        mMimeType = mimeType
    }

    fun pick(context: Context, fileSelectCallBack: FileSelectCallBack) {
        mFileSelectCallBack.set(fileSelectCallBack)
        startActivityForResult(context, createChooseIntent(mMimeType, mIsMultiSelect), mRequestCode)
        reset()
    }

    private fun reset() {
        mMimeType = FileMimeType.ALLTYPE
        mIsMultiSelect = false
    }

    private fun startActivityForResult(context: Any, intent: Intent, requestCode: Int) {
        if (context is Activity) {
            if (!context.isFinishing && !context.isDestroyed) {
                context.startActivityForResult(intent, requestCode)
            }
        } else if (context is Fragment) {
            val act: Activity? = context.activity
            if (act?.isFinishing == false && !act.isDestroyed) {
                context.startActivityForResult(intent, requestCode)
            }
        } else if (context is android.app.Fragment) {
            val act: Activity? = context.activity
            if (act?.isFinishing == false && !act.isDestroyed) {
                context.startActivityForResult(intent, requestCode)
            }
        }
    }

    fun parseResult(
        context: Context,
        requestCode: Int,
        resultCode: Int,
        intent: Intent?
    ): Boolean {
        if (intent == null) return false
        if (requestCode != mRequestCode) return false
        val callback = mFileSelectCallBack.get() ?: return true
        if (mIsMultiSelect) {
            handleMultiSelectCase(context, intent, callback)
        } else {
            handleSingleSelectCase(context, intent, callback)
        }
        return true
    }

    private fun handleSingleSelectCase(
        context: Context,
        intent: Intent,
        callBack: FileSelectCallBack
    ) {
        val intentData: Uri? = intent.data
        if (intentData == null) {
            callBack.onError(Throwable("intent?.data == null"))
            return
        }
        callBack.onSuccess(Collections.singletonList(FileSelectResult(intentData)))
    }

    private fun handleMultiSelectCase(
        context: Context, intent: Intent,
        callBack: FileSelectCallBack
    ) {
        val clipData = intent.clipData
        if (clipData == null) {
            if (intent.data == null) {
                callBack.onError(Throwable("intent?.clipData == null"))
            } else {
                handleSingleSelectCase(context, intent, callBack)
            }
            return
        }
        val resultList = mutableListOf<FileSelectResult>()
        for (idx in 0 until clipData.itemCount) {
            val uri = clipData.getItemAt(idx)?.uri ?: continue
            resultList.add(FileSelectResult(uri))
        }
        if (resultList.isEmpty()) {
            callBack.onError(Throwable("select result is empty , maybe all uri is null"))
            return
        }
        callBack.onSuccess(resultList)
    }
}